package com.moji.controller.api;


import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.moji.common.base.ApiResult;
import com.moji.entity.*;
import com.moji.entity.dto.AddOrderDto;
import com.moji.entity.dto.MjOrderCommon;
import com.moji.entity.dto.OrderRefusedDto;
import com.moji.entity.dto.QueryOrderDto;
import com.moji.entity.vo.*;
import com.moji.service.*;

import com.moji.service.impl.AlipayService;
import com.moji.service.impl.WeChatService;
import com.moji.util.DateUtils;
import com.moji.util.MoJiCommonUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.http.util.TextUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 订单表 前端控制器
 * </p>
 *
 * @author ccl
 * @since 2024-07-27
 */
@RestController
@RequestMapping("web/auth/mjOrder")
@Api(tags = "订单管理web相关接口(控制中心)", value = "订单管理web相关接口(控制中心)")
public class MjOrderController {
    @Autowired
    private AlipayService alipayService;
    @Autowired
    private WeChatService weChatService;
    @Resource
    private MjOrderService mjOrderService;
    @Resource
    private MjAgreementService mjAgreementService;
    @Resource
    private MjOrderDetailService mjOrderDetailService;
    @Resource
    private MjCarService mjCarService;
    @Resource
    private MjFlowConfigService mjFlowConfigService;
    @Resource
    private MjFlowService mjFlowService;
    @Resource
    private SysMessageService sysMessageService;

    @PostMapping("/add")
    @ApiOperation(value = "订单_新增", response = Boolean.class)
    public ApiResult add(@Validated @RequestBody AddOrderDto addOrderDto) {
        for (int i = 0; i < addOrderDto.getOrderDetailList().size(); i++) {
            if (!"免费版".equals(addOrderDto.getOrderDetailList().get(i).getOrderName())) {
                if (addOrderDto.getOrderDetailList().get(i).getAmount() == null || addOrderDto.getOrderDetailList().get(i).getAmount().compareTo(BigDecimal.ZERO) == 0) {
                    return ApiResult.failed("下单失败，请联系客服人员");
                }
            }
        }
        MjOrder mjOrder = mjOrderService.add(addOrderDto);
        if (mjOrder == null) {
            return ApiResult.failed("订单新增失败");
        }
        return ApiResult.ok(mjOrder);
    }

    @PostMapping("/edit")
    @ApiOperation(value = "订单_编辑", response = Boolean.class)
    public ApiResult edit(@Validated @RequestBody AddOrderDto addOrderDto) {
        return ApiResult.ok(mjOrderService.edit(addOrderDto));
    }

    @GetMapping("/delete")
    @ApiOperation(value = "订单_删除", response = Boolean.class)
    public ApiResult delete(@RequestParam("id") Long id) {
        return ApiResult.ok(mjOrderService.delete(id));
    }

    @PostMapping("/queryByPage")
    @ApiOperation(value = "订单_分页查询", response = ApiResult.class)
    public ApiResult queryByPage(@RequestBody QueryOrderDto dto) {
        return ApiResult.ok(mjOrderService.queryByPage(dto));
    }

    @GetMapping("/detail")
    @ApiOperation(value = "订单_详情", response = MjOrder.class)
    public ApiResult detail(@RequestParam("id") Long id) {
        return ApiResult.ok(mjOrderService.detail(id));
    }


    /**
     * 提交订单
     */
    @ApiOperation("提交订单")
    @PostMapping("/commit")
    public ApiResult<CorporateAccount> commitOrder(@RequestBody MjOrder param) {
        try {
            MjOrder one = mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>().eq(MjOrder::getOrderCode, param.getOrderCode()));
            Date date = new Date();
            one.setUpdateTime(date);
            if ("1".equals(one.getProductType())) {
                one.setOrderStatus(1);
                one.setPayType("3");
            } else {
                one.setOrderStatus(0);
                one.setPayType(param.getPayType());
            }
            mjOrderService.updateById(one);

            List<MjOrderDetail> mjOrderDetails = mjOrderDetailService.list(new LambdaQueryWrapper<MjOrderDetail>()
                    .eq(MjOrderDetail::getOrderCode, one.getOrderCode()));
            if (ObjectUtil.isNotEmpty(mjOrderDetails)) {
                mjOrderDetails.forEach(mjOrderDetail -> {
                    //下单成功消息通知
                    SysMessage sysMessage = new SysMessage();
                    sysMessage.setReceiveUserId(one.getCreateId());
                    sysMessage.setSendUserId(MoJiCommonUtils.getUserCode());
                    sysMessage.setMarkAsRead(0);
                    sysMessage.setMessageTitle("下单成功");
                    //消息类型 1-发票提醒 2-下单成功 3-待支付提醒4-超时未支付 5-工单回复 6-工单完结 7-服务到期提醒
                    sysMessage.setMessageType("2");
                    sysMessage.setMessageCenter("尊敬的用户您好：您于" + DateUtils.formatDate(mjOrderDetail.getCreateTime(), DateUtils.DATE_FORMAT_EXP1) + "成功购买的“包年”服务，" +
                            "订单编号为：" + one.getOrderCode() + "生效时间为" + DateUtils.formatDate(mjOrderDetail.getEffectTime(), DateUtils.DATE_FORMAT_EXP1) + "，如有疑问请联系客服010-84798388转8042!");
                    sysMessage.setBillNo(one.getId() + "");
                    sysMessage.setBillTypeCode("2");
                    sysMessage.setCreateId(MoJiCommonUtils.getUserCode());
                    sysMessage.setUpdateId(MoJiCommonUtils.getUserCode());
                    sysMessage.setCreateTime(new Date());
                    sysMessage.setUpdateTime(new Date());
                    sysMessageService.add(sysMessage);
                });
            }
            CorporateAccount corporateAccount = new CorporateAccount();
            corporateAccount.setOrderCode(param.getOrderCode());
            corporateAccount.setAmount(param.getOrderAmount() + "");
            corporateAccount.setRemark(param.getRemark());
            return ApiResult.ok(corporateAccount);
        } catch (Exception e) {
        }
        return ApiResult.failed("提交失败");
    }


    @ApiOperation("获取支付宝收款二维码")
    @PostMapping(value = "/getAlipayQrcode")
    public ApiResult<String> getAlipayQrcode(@RequestBody MjOrderCommon mjOrderCommon) {
        MjOrder order = mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>().eq(MjOrder::getOrderCode, mjOrderCommon.getOrderCode()));
        try {
            String codeUrl = alipayService.pay(order);
            return ApiResult.ok(codeUrl);
        } catch (Exception e) {

        }
        //return ApiResponseT.builder().fail("订单提交失败,请重试!");
        return ApiResult.failed("");
    }

    //保存订单信息并生成订单号返回
    @ApiOperation("获取微信收款二维码")
    @PostMapping("/getWechatPayQrcode")
    public void getPayQrcode(@ApiParam("订单编号") @RequestBody MjOrderCommon mjOrderCommon, HttpServletRequest request, HttpServletResponse response) {
        MjOrder order = mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>().eq(MjOrder::getOrderCode, mjOrderCommon.getOrderCode()));
        try {
            String codeUrl = weChatService.unifiedOrder(order);
            if (codeUrl == null) {
                throw new NullPointerException();
            }
            //生成二维码配置
            Map<EncodeHintType, Object> hints = new HashMap<>();

            //设置纠错等级
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
            //编码类型
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

            BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE, 400, 400, hints);
            OutputStream out = response.getOutputStream();

            MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
        } catch (Exception e) {

        }
        //return ApiResponseT.builder().fail("订单提交失败,请重试!");
    }

    @ApiOperation("获取支付状态")
    @PostMapping("/getPayStaus")
    public ApiResult<Integer> getPayStaus(@RequestBody MjOrderCommon mjOrderCommon) {
        MjOrder order = mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>().eq(MjOrder::getOrderCode, mjOrderCommon.getOrderCode()));
        if (order != null) {
            Integer status = order.getOrderStatus();
            return ApiResult.ok(status);
        }
        return ApiResult.failed("暂无状态");
    }

    @ApiOperation("更换支付方式")
    @PostMapping("/updatePayType")
    public ApiResult<Boolean> updatePayType(@RequestBody MjOrderCommon mjOrderCommon) {
        MjOrder order = mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>().eq(MjOrder::getOrderCode, mjOrderCommon.getOrderCode()));
        if (order != null) {
            order.setPayType(mjOrderCommon.getPayType());
            mjOrderService.updateById(order);
            return ApiResult.ok(Boolean.TRUE);
        }
        return ApiResult.failed("更新失败");
    }

    @ApiOperation("申请退款")
    @PostMapping("/requestRefund")
    public ApiResult<Boolean> requestRefund(@RequestBody OrderRefusedDto orderRefusedDto) {
        //增加流程配置校验
        MjFlowConfig mjFlowConfig = mjFlowConfigService.getOne(new LambdaQueryWrapper<MjFlowConfig>()
                .eq(MjFlowConfig::getFlowType, 3));
        if (mjFlowConfig == null) {
            throw new RuntimeException("您暂时无法发起申请退款，请联系人工客服");
        }
        MjOrder order = mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>().eq(MjOrder::getOrderCode, orderRefusedDto.getOrderCode()));
        if (order != null) {
            if (order.getOrderStatus() != 1 && order.getOrderStatus() != 7) {
                throw new RuntimeException("当前订单状态暂无法发起申请退款，请稍后再试");
            }
            if (order.getSpareInt1() == null) {
                order.setSpareInt1(1);
                order.setSpareString2(orderRefusedDto.getApplicationReason() + "application-" + orderRefusedDto.getApplicationRemark());
            } else {
                if (order.getSpareInt1() == 3) {
                    return ApiResult.failed("您已无法发起申请退款，请联系人工客服");
                } else {
                    Integer spareInt1 = order.getSpareInt1();
                    order.setSpareInt1(spareInt1 + 1);
                    order.setSpareString2(order.getSpareString2() + "###---" + orderRefusedDto.getApplicationReason() + "application-" + orderRefusedDto.getApplicationRemark());
                }
            }
            Integer status = order.getOrderStatus();
            if (status == 1 || status == 7) {
                order.setOrderStatus(3);
                order.setApplicationRemark(orderRefusedDto.getApplicationRemark());
                order.setApplicationReasonId(orderRefusedDto.getApplicationReasonId());
                order.setApplicationReason(orderRefusedDto.getApplicationReason());
                //审核状态20 - 审核中 21-已审核 22-已驳回
                order.setAuditStatus(20);
                order.setOrderStatus(3);
                mjOrderService.updateById(order);
                //需要提交审批流程,流程审批插入数据
                MjFlow mjFlow = new MjFlow();
                mjFlow.setFlowName("申请退款");
                mjFlow.setProductCode(order.getProductCode());
                mjFlow.setProductType(order.getProductType());
                mjFlow.setProductName(order.getProductName());
                mjFlow.setOrderCode(order.getOrderCode());
                mjFlow.setOrdertName(order.getOrderName());
                mjFlow.setOrderAmount(order.getOrderAmount());
                mjFlow.setNewOrderAmount(order.getOrderAmount());
                mjFlow.setEditOrderAmount(order.getOrderAmount());
                //审核状态10 - 未提交 11 - 已提交
                mjFlow.setSubmitStatus(11);
                mjFlow.setSubmitTime(new Date());
                mjFlow.setSubmitCode(MoJiCommonUtils.getUserCode());
                mjFlow.setSubmitName(MoJiCommonUtils.getUserName());
                //审核状态 20 - 审核中 21-已审核 22-已驳回
                mjFlow.setAuditStatus(20);
                mjFlow.setCreateId(MoJiCommonUtils.getUserCode());
                mjFlow.setUpdateId(MoJiCommonUtils.getUserCode());
                mjFlow.setCreateTime(new Date());
                mjFlow.setUpdateTime(new Date());
                //记录审核流转节点
                mjFlow.setSpareInt1(1);
                //流程类型
                mjFlow.setFlowType("3");
                mjFlow.setFlowName("申请退款");
                mjFlowService.save(mjFlow);

                return ApiResult.ok(true);
            }
        }
        return ApiResult.failed("提交失败");
    }

    @GetMapping("/download")
    @ApiOperation(value = "订单_合同下载", response = ApiResult.class)
    public ApiResult<String> download(HttpServletResponse response) {
        String url = "";
        LambdaQueryWrapper<MjAgreement> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MjAgreement::getType, 4);
        MjAgreement mjAgreement = mjAgreementService.getOne(wrapper);
        if (mjAgreement != null) {
            url = mjAgreement.getUrl();
        }
        return ApiResult.ok(url);
    }

    @ApiOperation("取消订单")
    @PostMapping("/cancleOrder")
    public ApiResult<Boolean> cancleOrder(@RequestBody MjOrderCommon mjOrderCommon) {
        MjOrder order = mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>().eq(MjOrder::getOrderCode, mjOrderCommon.getOrderCode()));
        if (order != null) {
            order.setOrderStatus(2);
            return ApiResult.ok(mjOrderService.updateById(order));
        }
        return ApiResult.failed("取消失败");
    }

    @ApiOperation("续订订单")
    @GetMapping("/renew")
    public ApiResult<MjOrder> renewOrder(@RequestParam("orderCode") String orderCode) {
        //续订订单需要提交一个新得订单号，将原来的信息复制过来
        MjOrder order = mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>().eq(MjOrder::getOrderCode, orderCode));
        if (order != null) {
            List<MjOrderDetail> list = mjOrderDetailService.list(new LambdaQueryWrapper<MjOrderDetail>().eq(MjOrderDetail::getOrderCode, orderCode));
            for (int i = 0; i < list.size(); i++) {
                list.get(i).setEffectTime(new Date());
            }
            AddOrderDto addOrderDto = new AddOrderDto();
            addOrderDto.setOrderDetailList(list);
            BeanUtils.copyProperties(order, addOrderDto);
            addOrderDto.setId(null);
            addOrderDto.setPayType(null);
            addOrderDto.setOrderStatus(0);
            addOrderDto.setAuditStatus(null);
            addOrderDto.setUseStatus(null);
            addOrderDto.setBillStatus(null);
            addOrderDto.setCreateTime(new Date());
            MjOrder add = mjOrderService.add(addOrderDto);
            return ApiResult.ok(add);
        }
        return ApiResult.failed("续订失败");
    }

    @PostMapping("/statistics")
    @ApiOperation(value = "订单_统计", response = StatisticsVo.class)
    public ApiResult<StatisticsVo> statistics(@RequestBody QueryOrderDto dto) {
        return ApiResult.ok(mjOrderService.statistics(dto));
    }

    @GetMapping("/brief")
    @ApiOperation(value = "调用总次数", response = MijiMoYaoVo2.DataBean.class)
    public ApiResult<MijiMoYaoVo2.DataBean> brief(@ApiParam("多个使用逗号分离") @RequestParam("tokens") String tokens) {
        return ApiResult.ok(mjOrderService.brief(tokens));
    }

    @GetMapping("/tsdata")
    @ApiOperation(value = "获取指定Token时间范围调用计数", response = MijiMoYaoVo2.DataBean.class)
    public ApiResult<MijiMoYao3.DataBean> tsData(@ApiParam("多个使用逗号分离") @RequestParam("tokens") String tokens, @ApiParam("hourly：逐小时  daily：逐日  monthly：逐月  weekly：逐周") @RequestParam("aggType") String aggType,
                                                 @ApiParam("开始时间 格式为 yyyy-MM-dd HH:mm") @RequestParam("startTime") String startTime, @ApiParam("结束时间 格式为 yyyy-MM-dd HH:mm") @RequestParam("endTime") String endTime) {
        return ApiResult.ok(mjOrderService.tsData(tokens, aggType, startTime, endTime));
    }

    @ApiOperation("订单退款历史记录")
    @GetMapping("/refuseHistory")
    public ApiResult<List<RefuseHistoryVO>> refuseHistory(@RequestParam("orderCode") String orderCode) {
        //获取次数，然后再获取拒绝理由
        LambdaQueryWrapper<MjFlow> mjFlowLambdaQueryWrapper = new LambdaQueryWrapper<MjFlow>().eq(MjFlow::getOrderCode, orderCode).eq(MjFlow::getFlowName, "申请退款");
        List<MjFlow> list = mjFlowService.list(mjFlowLambdaQueryWrapper);
        List<RefuseHistoryVO> refuseHistoryVOList = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                RefuseHistoryVO refuseHistoryVO = new RefuseHistoryVO();
//                refuseHistoryVO.setRefuseType("正常退款");
                refuseHistoryVO.setApplyDate(list.get(i).getCreateTime());
                refuseHistoryVO.setAuditStatus(list.get(i).getAuditStatus());
                if (list.get(i).getAuditStatus() == 20) {
                    refuseHistoryVO.setExamineResult("审核中");
                } else if (list.get(i).getAuditStatus() == 21) {
                    refuseHistoryVO.setExamineResult("审核通过");
                } else if (list.get(i).getAuditStatus() == 22) {
                    refuseHistoryVO.setExamineResult("审核未通过");
                    refuseHistoryVO.setRefuseDate(list.get(i).getUpdateTime());
                }
                MjOrder order = mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>().eq(MjOrder::getOrderCode, orderCode));
                if (order != null) {
                    if (order.getSpareInt1() == 1) {
                        if (!TextUtils.isEmpty(order.getSpareString2())) {
                            if (order.getSpareString2().split("application-") != null && order.getSpareString2().split("application-").length > 1) {
                                String[] split = order.getSpareString2().split("application-");
                                refuseHistoryVO.setRefuseType(split[0] + "");
                                refuseHistoryVO.setRefundReson(split[1] + "");
                            }
                        }
                    } else {
                        if (order.getSpareString2() != null) {
                            if (order.getSpareString2().split("###---") != null) {
                                String[] split = order.getSpareString2().split("###---");
                                if (split.length >= i) {
                                    String s = split[i];
                                    if (s.split("application-") != null && s.split("application-").length > 1) {
                                        String[] split1 = s.split("application-");
                                        refuseHistoryVO.setRefuseType(split1[0] + "");
                                        refuseHistoryVO.setRefundReson(split1[1] + "");
                                    }
                                }
                            }
                        }
                    }


                }
                if (list.get(i).getReason() == null) {
                    refuseHistoryVO.setRefuseReson("");
                } else {
                    refuseHistoryVO.setRefuseReson(list.get(i).getReason() + "");
                }

                refuseHistoryVOList.add(refuseHistoryVO);
            }


        }
        return ApiResult.ok(refuseHistoryVOList);
    }
}

